package com.mini.gateway.web.controller;

import com.mini.gateway.core.filter.ElapsedTimeGatewayFilterFactory;
import com.mini.gateway.core.modules.route.dto.RouteView;
import com.mini.gateway.core.modules.route.entity.RouteParam;
import com.mini.gateway.core.modules.route.entity.MiniRoute;
import com.mini.gateway.core.modules.route.enums.ParamType;
import com.mini.gateway.core.modules.route.enums.RouteType;
import com.mini.gateway.core.modules.route.service.RouteService;
import com.mini.gateway.web.controller.vo.RouteVO;
import com.mini.gateway.web.domain.JsonResult;
import com.mini.gateway.web.domain.LayTableResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactory;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * PageController
 *
 */
@Controller
@RequestMapping("/gateway/route")
public class RouteController {

    @Autowired
    private RouteService routeService;

    @GetMapping("/page/list")
    public Mono<String> toListPage(final Model model) {
        List<RouteView> routeList = routeService.getRouteList();
        model.addAttribute("routeList", routeList);
        return Mono.create(monoSink -> monoSink.success("route/route_list"));
    }

    @GetMapping(value = "/data/list")
    @ResponseBody
    public Mono<LayTableResult<RouteView>> listData() {
        List<RouteView> routeList = routeService.getRouteList();
        return Mono.just(LayTableResult.success(routeList));
    }

    @GetMapping(value = "/page/add")
    public Mono<String> toAddPage() {
        return Mono.create(monoSink -> monoSink.success("route/route_add"));
    }

    @PostMapping(value = "/add")
    @ResponseBody
    public Mono<JsonResult> doAdd(RouteVO vo) {
        MiniRoute miniRoute = new MiniRoute(RouteType.CUSTOMIZE, vo.getName(), vo.getPath(), vo.getUri(), vo.getOrders());
        routeService.addRoute(miniRoute, vo.isEnableHystrix(), vo.getHystrixValue(), vo.isEnableLog());
        return Mono.just(JsonResult.success());
    }

    @GetMapping(value = "/page/edit/{id}")
    public Mono<String> toEditPage(@PathVariable("id") Integer id, final Model model) {
        MiniRoute route = routeService.getRoute(id);
        model.addAttribute("route", route);

        boolean enableHystrix = false;
        boolean enableLog = false;
        List<RouteParam> paramList = routeService.getRouteParamList(route.getId(), ParamType.FILTER);
        for (RouteParam _param : paramList) {
            if (_param.getName().equals(NameUtils.normalizeFilterFactoryName(HystrixGatewayFilterFactory.class))) {
                enableHystrix = true;
            } else if (_param.getName().equals(NameUtils.normalizeFilterFactoryName(ElapsedTimeGatewayFilterFactory.class))) {
                enableLog = true;
            }
        }
        model.addAttribute("enableHystrix", enableHystrix);
        model.addAttribute("enableLog", enableLog);

        return Mono.create(monoSink -> monoSink.success("route/route_edit"));
    }

    @PutMapping(value = "/edit")
    @ResponseBody
    public Mono<JsonResult> doEdit(RouteVO vo) {
        routeService.update(vo.getId(), vo.getPath(), vo.getUri(), vo.getOrders(), vo.isEnableHystrix(), vo.getHystrixValue() == null ? 0 : vo.getHystrixValue(), vo.isEnableLog());
        return Mono.just(JsonResult.success());
    }


}
